home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
Talking Telnet
/
source
/
ae
/
ae.c
next >
Wrap
Text File
|
1996-06-22
|
8KB
|
309 lines
/*
* ae.c
* Code to handle the AppleEvents we recognize
*****************************************************************
* NCSA Telnet for the Macintosh *
* *
* National Center for Supercomputing Applications *
* Software Development Group *
* 152 Computing Applications Building *
* 605 E. Springfield Ave. *
* Champaign, IL 61820 *
* *
* Copyright (c) 1986-1994, *
* Board of Trustees of the University of Illinois *
****************************************************************/
#include "wind.h" // For connections.proto.h
#include "ae.proto.h"
#include "connections.proto.h" // For OpenConnectionFromURL proto
#include "Sets.proto.h" // For readconfig proto
#include "macros.proto.h" // For loadMacro proto
#include "menuseg.proto.h" // For HandleQuit proto
#include "debug.h" // For ShowDebugWindow proto
static void ProcessURLEscapeCodes (char *url, char **end);
void AEunload(void) { }
SIMPLE_UPP(MyHandleODoc, AEEventHandler);
pascal OSErr MyHandleODoc (AppleEvent *theAppleEvent, AppleEvent* reply, long
handlerRefCon)
{
FSSpec myFSS;
AEDescList docList;
OSErr err;
long index, itemsInList;
Size actualSize;
AEKeyword keywd;
DescType returnedType;
FInfo fileInfo;
if ((err = AEGetParamDesc (theAppleEvent, keyDirectObject, typeAEList, &docList)) != noErr)
return err;
// check for missing parameters
if ((err = MyGotRequiredParams (theAppleEvent)) != noErr)
return err;
// count the number of descriptor records in the list
if ((err = AECountItems (&docList, &itemsInList)) != noErr)
return err;
for (index = 1; index <= itemsInList; index++) {
err = AEGetNthPtr (&docList, index, typeFSS, &keywd, &returnedType,
(Ptr) &myFSS, sizeof(myFSS), &actualSize);
if (err) return err;
FSpGetFInfo(&myFSS, &fileInfo); /* make sure it's a data file */
if (fileInfo.fdCreator == kNCSACreatorSignature && fileInfo.fdType == kNCSASetFileType)
readconfig(myFSS); // Read the actual set
else if(fileInfo.fdCreator == kNCSACreatorSignature && fileInfo.fdType == 'TEXT')
loadMacros(&myFSS);
else if (fileInfo.fdCreator == kNCSACreatorSignature && fileInfo.fdType == 'DBUG')
{
TelInfo->debug = TRUE;
ShowDebugWindow();
}
}
err = AEDisposeDesc (&docList);
return noErr;
}
SIMPLE_UPP(MyHandlePDoc, AEEventHandler);
pascal OSErr MyHandlePDoc (AppleEvent *theAppleEvent, AppleEvent *reply, long
handlerRefCon)
{
// We don't print files.
return (errAEEventNotHandled);
}
SIMPLE_UPP(MyHandleOApp, AEEventHandler);
pascal OSErr MyHandleOApp (AppleEvent *theAppleEvent, AppleEvent *reply, long
handlerRefCon)
{
// Don't need to do anything for OApp.
return noErr;
}
SIMPLE_UPP(MyHandleQuit, AEEventHandler);
pascal OSErr MyHandleQuit (AppleEvent *theAppleEvent, AppleEvent *reply, long
handlerRefCon)
{
if (HandleQuit())
return(-128); // userCancelledErr
return(noErr);
}
SIMPLE_UPP(MyHandleGURL, AEEventHandler);
pascal OSErr MyHandleGURL (AppleEvent *theAppleEvent, AppleEvent* reply, long
handlerRefCon)
{
OSErr err;
DescType returnedType;
Size actualSize;
char URLString[255];
char *beg, *end, *user, *password, *portstring, *host;
if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType,
URLString, sizeof(URLString)-1, &actualSize)) != noErr)
return err;
// check for missing parameters
if ((err = MyGotRequiredParams(theAppleEvent)) != noErr)
return err;
URLString[actualSize] = 0; // Terminate the C string
beg = &URLString[0];
end = &URLString[actualSize-1];
// Strip leading spaces
while ((beg < end) && (*beg == ' '))
beg++;
// Strip trailing spaces
while ((end < beg) && (*end == ' '))
end--;
// Look for (and strip) beginning and ending angle brackets
if (*beg == '<') {
if (*end != '>') { // Leading angle bracket, but no trailing angle bracket
err = paramErr;
goto badExit;
}
// Nuke the brackets
beg++;
end--;
}
// Terminate the string we currently have (for strncmp fn's)
*(end+1) = 0;
// Look for (and strip) leading "URL:"
if (!strncmp(beg, "URL:", 4)) {
beg += 4;
}
// Look for (and strip) leading "telnet://"
if (strncmp(beg, "telnet://", 9)) // No leading "telnet://"
{
if (strncmp(beg, "rlogin://", 9))
{
err = paramErr;
goto badExit;
}
}
beg += 9;
// Drop any ending slash
if (*end == '/') {
*end = 0;
end--;
}
// Process any escaped characters
ProcessURLEscapeCodes(beg, &end);
// Set up for URL parsing
password = nil;
portstring = nil;
host = nil;
// Assume <user> exists
user = beg;
// Leading : or @ is a no-no
if ((*beg == ':') || (*beg == '@')) {
err = paramErr;
goto badExit;
}
// Scan for : or @ or end of string
while ((beg <= end) && (*beg != ':') && (*beg != '@'))
beg++;
// If we reached the end, only a host was given
if (beg > end) {
host = user;
user = nil;
goto goodUrl;
}
// If : was found, scan in the password (or port)
if (*beg == ':') {
*beg++ = 0;
password = beg;
// Scan for : or @ or end of string
while ((beg <= end) && (*beg != ':') && (*beg != '@'))
beg++;
if (*beg == ':') { // xxxx:yyyy:<anything> is a no-no
err = paramErr;
goto badExit;
}
if (*beg != '@') { // End of string. Must be host:port
host = user;
user = nil;
portstring = password;
password = nil;
goto goodUrl;
}
// Have xxx:yyy@<something>
*beg++ = 0; // Terminate password string
}
else { // Found @
*beg++ = 0; // Terminate user string
}
// Ok at this point have xxx:yyy@<something> or xxxx@<something>
host = beg;
// Scan for : or @ or end of string
while ((beg <= end) && (*beg != ':') && (*beg != '@') && (*beg != '/')) //CCP fix bad telnets
beg++;
if (*beg == '@') { //xxx[:yyyy]@xxx@ is a no-no
err = paramErr;
goto badExit;
}
if (*beg != ':') { // End of string, we have xxxx[:yyyy]@zzzz
*beg = 0;
}
else {
*beg++ = 0; // Terminate host string
portstring = beg;
}
goodUrl:
OpenConnectionFromURL(host, portstring, user, password);
err = noErr;
badExit:
return err;
}
/*----------------------------------------------------------------------------
ProcessURLEscapeCodes
Process "%xx" escape codes in a URL string (replace them by the characters
they represent).
Entry: url = URL with escape codes.
Exit: url = URL with escape codes replaced by the characters they
represent.
Copyright © 1994, Northwestern University.
Modified 12/94 Jim Browne for NCSA
----------------------------------------------------------------------------*/
static void ProcessURLEscapeCodes (char *url, char **end)
{
char *p, *q;
char c1, c2;
p = q = url;
while (*p != 0) {
if (*p == '%') {
c1 = tolower(*(p+1));
c2 = tolower(*(p+2));
if (isxdigit(c1) && isxdigit(c2)) {
c1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
c2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
*q++ = (c1 << 4) + c2;
p += 3;
} else {
*q++ = *p++;
}
} else {
*q++ = *p++;
}
}
*q = 0;
*end = q-1;
}
OSErr MyGotRequiredParams (AppleEvent *theAppleEvent)
{
DescType returnedType;
Size actualSize;
OSErr err;
err = AEGetAttributePtr (theAppleEvent, keyMissedKeywordAttr,
typeWildCard, &returnedType, nil, 0,
&actualSize);
if (err == errAEDescNotFound) // you got all the required parameters
return noErr;
else if (!err) // you missed a required parameter
return errAEEventNotHandled;
else // the call to AEGetAttributePtr failed
return err;
}